package cn.pdx.elec.service.impl;



import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


import cn.pdx.elec.dao.ElecRolePopedomDao;
import cn.pdx.elec.dao.ElecUserRoleDao;
import cn.pdx.elec.domain.ElecRolePopedom;
import cn.pdx.elec.domain.ElecUserRole;
import cn.pdx.elec.service.ElecRoleService;
import cn.pdx.elec.util.XmlObject;
import cn.pdx.elec.web.form.ElecRoleForm;
import cn.pdx.elec.web.form.ElecUserForm;


/**
 *  @Repository 、@Service 和 @Controller 
           在目前的 Spring 版本中，这 3 个注释和 @Component 是等效的，但是从注释类的命名上，3 个注释分别和持久层 、业务层 和控制层 相对应。
 * 
 *@Transactional(readOnly=true),定义类方法的事务为只读,不能写入数据库
 * 业务类方法只有增、删、改为可写,其他事务都为只读
 * @author 彭定旭
 */
@Transactional(readOnly=true)
@Service(ElecRoleService.SERVICE_NAME)   //spring不用配置
public class ElecRoleServiceImpl implements ElecRoleService {
   
	//业务层调用dao层;用注解
	@SuppressWarnings("unused")
	@Resource(name=ElecUserRoleDao.SERVICE_NAME)
	private ElecUserRoleDao elecUserRoleDao;
	
	
	@SuppressWarnings("unused")
	@Resource(name=ElecRolePopedomDao.SERVICE_NAME)
	private ElecRolePopedomDao elecRolePopedomDao;


	/**
	 * @Name:readXml
	 * @Description:从Function.xml文件中查询系统所有的功能权限存放到XmlObject对象中
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-13(创建日期)
	 * @parameters:无
	 * @return:List<XmlObject> 权限集合
	 */
	public List<XmlObject> readXml() {
		
		ServletContext servletContext=ServletActionContext.getServletContext();
		
		//ervletContext.getRealPath只是到了C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\dianli_system这里而已
		String realpath=servletContext.getRealPath("/WEB-INF/classes/Function.xml");
		
		File f=new File(realpath);
		
		//使用dom4j读配置文件
		SAXReader saxReader=new SAXReader();
		
		List<XmlObject> xmlList=new ArrayList<XmlObject>();
		
		try {
			
			Document document=saxReader.read(f);
			
			//获取元素集合
			Element element=document.getRootElement();
			
			XmlObject xmlObject=null;
			
			
			/**
			 * Function:对应配置文件中的Function元素节点
			 * FunctionCode：对应配置文件中Function元素节点下的FunctionCode元素节点
			 * FunctionName：对应配置文件中Function元素节点下的FunctionName元素节点
			 * ParentCode：对应配置文件中Function元素节点下的ParentCode元素节点
			 * ParentName：对应配置文件中Function元素节点下的ParentName元素节点
			 */
			//遍历元素Function集合
			for(Iterator<Element> iterator=element.elementIterator("Function");iterator.hasNext();)
			{
				Element xmlElement= iterator.next();
				xmlObject=new XmlObject();
				
				xmlObject.setCode(xmlElement.elementText("FunctionCode"));
				xmlObject.setName(xmlElement.elementText("FunctionName"));
				xmlObject.setParentCode(xmlElement.elementText("ParentCode"));
				xmlObject.setParentName(xmlElement.elementText("ParentName"));
				xmlList.add(xmlObject);
			}
			
		} catch (DocumentException e) {
			
			e.printStackTrace();
		}
		
		return xmlList;
	}


	/**
	 * @Name:readEditXml
	 * @Description:使用角色ID查询该角色下该有的权限，并与系统中所有的权限匹配
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-13(创建日期)
	 * @parameters:String roleID 角色ID
	 * @return:List<XmlObject> 权限集合
	 */
	public List<XmlObject> readEditXml(String roleID) {
		
		//使用roleID查询该角色下该有的权限
		ElecRolePopedom elecRolePopedom=elecRolePopedomDao.findObjectById(roleID);
		
		String popedom="";
		
		if(elecRolePopedom!=null)
		{
			//获取权限集合
			popedom=elecRolePopedom.getPopedomcode();
		}
		//与系统中的所有权限匹配
		List<XmlObject> list=this.readXmlByPopedom(popedom);
		
		return list;
	}

  
	/**
	 * @Name:readXmlByPopedom
	 * @Description:读取配置文件；获取系统所有的权限，与当前角色具有的权限进行匹配
	 *              如果匹配成功设置flag==0
	 *              不成功设置flag=1
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-13(创建日期)
	 * @parameters:SString popedom 权限集合
	 * @return:List<XmlObject> 权限集合（匹配完成）
	 */
	private List<XmlObject> readXmlByPopedom(String popedom) {
		
		List<XmlObject> list=new ArrayList<XmlObject>();
		
		//从配置文件里读出所以的权限
		List<XmlObject> xmlList=this.readXml();
		
		for(int i=0;xmlList!=null && i<xmlList.size();i++)
		{
			XmlObject xmlObject=xmlList.get(i);
			
			//表示如果查询出来的权限包含从配置文件里读出的字段,就是说明有，被选中
			if(popedom.contains(xmlObject.getCode()))
			{
				xmlObject.setFlag("1");
			}else{
				
				xmlObject.setFlag("0");
			}
			list.add(xmlObject);
		}
		return list;
	}


	/**
	 * @Name:findElecUserListByRoleID
	 * @Description:查询用户列表集合，获取系统中所有用户，与当前角色具有的用户进行匹配
	 *              如果匹配不成功设置flag==0，表示角色不拥有的用户,则页面复选框不被选中
	 *              成功设置flag=1,表示角色拥有的用户,则页面复选框被选中
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-15(创建日期)
	 * @parameters:String roleID 角色ID
	 * @return:List<ElecUserForm> 用户集合（匹配完成）
	 */
	public List<ElecUserForm> findElecUserListByRoleID(String roleID) {
		
		//底层方法没有
		List<Object []> list=elecUserRoleDao.findElecUserListByRoleID(roleID);
		
		List<ElecUserForm> formList=this.elecUserRoleObjectListToVoList(list);
		
		return formList;
	}

	

	/**
	 * @Name:elecUserRoleObjectListToVoList
	 * @Description:讲获取到的用户列表信息从OBject对象转换成VO对象
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-15(创建日期)
	 * @parameters:List<Object[]> list Object集合对象
	 * @return:List<ElecUserForm> VO对象
	 */
	private List<ElecUserForm> elecUserRoleObjectListToVoList(List<Object[]> list) {
		
		List<ElecUserForm> fromList=new ArrayList<ElecUserForm>();
		
		ElecUserForm elecUserForm=null;
		
		for(int i=0;list!=null && i<list.size();i++)
		{
			Object [] objects=list.get(i);
			elecUserForm=new ElecUserForm();
			elecUserForm.setFlag(objects[0].toString());
			elecUserForm.setUserID(objects[1].toString());
			elecUserForm.setUserName(objects[2].toString());
			elecUserForm.setLogonName(objects[3].toString());
			
			fromList.add(elecUserForm);
		}
		return fromList;
	}


	/**
	 * @Name:saveRole
	 * @Description:保存,保存角色与权限的关联表 
	 *                  保存角色与用户的关联表 
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-15(创建日期)
	 * @parameters:ElecRoleForm elecRoleForm VO对象,存放角色的ID、用户ID数组、权限code数组
	 * @return:无
	 */
	@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false)
	public void saveRole(ElecRoleForm elecRoleForm) {

		//保存角色和权限的关联表
		this.saveRolePopedom(elecRoleForm);
		
		//保存用户和角色的关联表
		this.saveUserRole(elecRoleForm);
	}



	/**
	 * @Name:saveUserRole
	 * @Description:保存,保存角色与权限的关联表 
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-20(创建日期)
	 * @parameters:ElecRoleForm elecRoleForm VO对象,存放角色的ID、用户ID数组
	 * @return:无
	 */
	private void saveUserRole(ElecRoleForm elecRoleForm) {

		//角色ID
		String roleid=elecRoleForm.getRoleid();
		//用户ID数组
		String [] selectuser=elecRoleForm.getSelectuser();
		/**
		 * 以roleId作为条件,查询用户和角色的关联表,获取用户和角色的关联集合对象
		 */
		
		String hqlWhere=" and o.roleID= ?";
		
		Object[] params={roleid};
		
		List<ElecUserRole> entities=elecUserRoleDao.findCollectionByConditionNoPage(hqlWhere, params, null);
		
		/**
		 * 以roleId作为条件,删除用户和角色的关联表
		 */
		elecUserRoleDao.deleteObjectByCollection(entities);
		System.out.println("fffffffffff");
		//新增用户和角色关联表
		List<ElecUserRole> list=new ArrayList<ElecUserRole>();
		for(int i=0;selectuser!=null && i<selectuser.length;i++)
		{
			String userID=selectuser[i];
			System.out.println("pppppppppp="+userID);
			ElecUserRole elecUserRole=new ElecUserRole();
			elecUserRole.setUserID(userID);
			elecUserRole.setRoleID(roleid);
			list.add(elecUserRole);
			
			/**
			elecUserRoleDao.save(elecUserRole); 这样也可以保存,但是保存集合对象好点
			 * 
			 */
		}
		elecUserRoleDao.saveObjectByCollection(list);
	}


	/**
	 * @Name:saveRole
	 * @Description:保存,保存角色与权限的关联表 
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-15(创建日期)
	 * @parameters:ElecRoleForm elecRoleForm VO对象,存放角色的ID、用户ID数组、权限code数组
	 * @return:无
	 */
	private void saveRolePopedom(ElecRoleForm elecRoleForm) {
   
		//角色ID
		String roleid=elecRoleForm.getRoleid();
		
		//权限code集合,数组
		String [] selectoper=elecRoleForm.getSelectoper();
		
		StringBuffer popedom=new StringBuffer("");
		
		//因为数组里面存放的是字符...a,b,c 要转换成字符串abcd....形式
		for(int i=0;selectoper!=null && i<selectoper.length;i++)
		{
			popedom.append(selectoper[i]);
		}
		
		System.out.println(popedom);
		//使用角色ID查询角色和权限的关联表,如果存在就update,否则就save
		ElecRolePopedom elecRolePopedom=elecRolePopedomDao.findObjectById(roleid);
		
		if(elecRolePopedom!=null)
		{
			//说明角色和关联表中存在该角色记录,执行update操作
			elecRolePopedom.setPopedomcode(popedom.toString());
			
			elecRolePopedomDao.update(elecRolePopedom);
		}
		else{
			
			//说明角色和关联表中存在该角色记录,执行save操作,先实例化对象
			elecRolePopedom=new ElecRolePopedom();
			elecRolePopedom.setRoleID(roleid);
			elecRolePopedom.setPopedomcode(popedom.toString());
			elecRolePopedomDao.save(elecRolePopedom);
		}
	}
  
	
	
	

	
}
